package com.common.shiro.dao;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.WebSessionKey;

import javax.servlet.ServletRequest;
import java.io.Serializable;

@Slf4j
public class DefaultRedisWebSessionManager extends DefaultWebSessionManager {
    @Override
    protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {
        // 获取SessionID
        Serializable sessionId = this.getSessionId(sessionKey);

        if (sessionId == null) {
            log.debug("Unable to resolve sessionId , sessionId 为 null" + sessionKey);
            return null;
        } else {
            if (sessionKey instanceof WebSessionKey) {
                WebSessionKey webSessionKey = ((WebSessionKey) sessionKey);
                ServletRequest servletRequest = webSessionKey.getServletRequest();
                if (servletRequest != null) {
                    // 从request域中获取session
                    Session session = (Session) servletRequest.getAttribute(sessionId + "");
                    if (session != null) {
                        log.info("从request域中获取session成功 : " + session);
                        return session;
                    } else {
                        // request中没有session，则从RedisSessionDAO中获取
                        session = this.retrieveSessionFromDataSource(sessionId);
                        log.info("从RedisSessionDAO中获取session成功,{}", session);
                        if (session == null) {
                            String msg = "Could not find session with ID [" + sessionId + "]";
                            throw new UnknownSessionException(msg);
                        } else {
                            // 将session保存到request域中, 下次对于同一请求会从request域中获取session
                            servletRequest.setAttribute(sessionId + "", session);
                            log.info("将session保存到request域中, 下次对于同一请求会从request域中获取session");
                            return session;
                        }
                    }
                }
            }
            return null;
        }
    }
}
